import { getToken } from '@/utils/auth'

class WebSocketClient {
  constructor() {
    this.websocket = null
    this.retryCount = 0
    this.maxRetryCount = 3
    this.retryDelay = 2000 // 重连延迟时间(ms)
    this.heartbeatInterval = null
    this.heartbeatIntervalTime = 30000 // 心跳间隔时间(ms)
    this.events = {}
    this.connected = false
  }

  /**
   * 连接WebSocket
   * @param {string} url WebSocket连接地址
   * @returns {Promise} 连接结果
   */
  connect(url) {
    return new Promise((resolve, reject) => {
      if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
        resolve(this.websocket)
        return
      }

      try {
        this.websocket = new WebSocket(url)

        // 连接成功事件
        this.websocket.onopen = () => {
          console.log('WebSocket连接成功')
          this.connected = true
          this.retryCount = 0
          this.startHeartbeat()
          this.fireEvent('open')
          resolve(this.websocket)
        }

        // 接收消息事件
        this.websocket.onmessage = (event) => {
          try {
            const data = JSON.parse(event.data)
            this.fireEvent('message', data)
          } catch (error) {
            console.error('解析WebSocket消息失败:', error)
            this.fireEvent('error', error)
          }
        }

        // 关闭连接事件
        this.websocket.onclose = () => {
          console.log('WebSocket连接关闭')
          this.connected = false
          this.stopHeartbeat()
          this.fireEvent('close')
          this.retryConnection(url)
        }

        // 连接错误事件
        this.websocket.onerror = (error) => {
          console.error('WebSocket连接错误:', error)
          this.connected = false
          this.fireEvent('error', error)
          reject(error)
        }
      } catch (error) {
        console.error('创建WebSocket连接失败:', error)
        reject(error)
      }
    })
  }

  /**
   * 断开WebSocket连接
   */
  disconnect() {
    if (this.websocket) {
      this.websocket.close()
      this.websocket = null
      this.connected = false
      this.stopHeartbeat()
    }
  }

  /**
   * 发送消息
   * @param {Object} data 消息数据
   */
  send(data) {
    if (!this.websocket || this.websocket.readyState !== WebSocket.OPEN) {
      console.error('WebSocket未连接，无法发送消息')
      return false
    }

    try {
      const message = typeof data === 'string' ? data : JSON.stringify(data)
      this.websocket.send(message)
      return true
    } catch (error) {
      console.error('发送WebSocket消息失败:', error)
      return false
    }
  }

  /**
   * 添加事件监听
   * @param {string} event 事件名称 (open/close/message/error)
   * @param {Function} callback 回调函数
   */
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = []
    }
    this.events[event].push(callback)
  }

  /**
   * 移除事件监听
   * @param {string} event 事件名称
   * @param {Function} callback 回调函数
   */
  off(event, callback) {
    if (!this.events[event]) return

    if (callback) {
      this.events[event] = this.events[event].filter(cb => cb !== callback)
    } else {
      this.events[event] = []
    }
  }

  /**
   * 触发事件
   * @param {string} event 事件名称
   * @param {any} data 事件数据
   */
  fireEvent(event, data) {
    if (!this.events[event]) return

    this.events[event].forEach(callback => {
      try {
        callback(data)
      } catch (error) {
        console.error(`执行${event}事件回调失败:`, error)
      }
    })
  }

  /**
   * 连接到实时竞赛WebSocket
   * @param {number} contestId 竞赛ID
   * @param {number} userId 用户ID
   * @returns {Promise} 连接结果
   */
  connectToLiveContest(contestId, userId) {
    const token = getToken()
    if (!token) {
      return Promise.reject(new Error('用户未登录'))
    }

    const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    // 优先使用环境变量中配置的WebSocket主机，如果没有则使用当前页面的主机
    const wsHost = process.env.VUE_APP_WS_HOST || window.location.host
    
    // 构建WebSocket URL
    const url = `${wsProtocol}//${wsHost}/ws/contest/${contestId}/${userId}/${token}`
    
    // 记录连接信息
    console.log(`尝试连接WebSocket: ${url}`)
    
    return this.connect(url)
      .catch(error => {
        console.error('WebSocket连接失败，详细信息:', {
          protocol: wsProtocol,
          host: wsHost,
          contestId,
          userId,
          error: error.message || error
        })
        throw error
      })
  }

  /**
   * 尝试重新连接
   * @param {string} url WebSocket连接地址
   */
  retryConnection(url) {
    if (this.retryCount >= this.maxRetryCount) {
      console.log('重连次数已达上限，不再重连')
      return
    }

    console.log(`${this.retryDelay / 1000}秒后尝试重连...`)
    setTimeout(() => {
      this.retryCount++
      console.log(`第${this.retryCount}次尝试重连`)
      this.connect(url).catch(() => {
        // 连接失败，会自动触发onclose事件，然后再次重连
      })
    }, this.retryDelay)
  }

  /**
   * 开始心跳检测
   */
  startHeartbeat() {
    this.stopHeartbeat()
    this.heartbeatInterval = setInterval(() => {
      if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
        this.send({ type: 'ping' })
      }
    }, this.heartbeatIntervalTime)
  }

  /**
   * 停止心跳检测
   */
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval)
      this.heartbeatInterval = null
    }
  }
}

// 创建单例
const websocket = new WebSocketClient()

export default websocket 